# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-07-15 23:20
# File     : cache_manager.py
# Project  : dynamic-portfolio-optimizer
# Desc     : 缓存管理器

import redis
import pickle
import hashlib
from typing import Any, Optional
from datetime import datetime, timedelta
import pandas as pd
import logging

logger = logging.getLogger(__name__)


class CacheManager:
    """数据缓存管理器"""

    def __init__(self, redis_host='localhost', redis_port=6379, redis_db=0):
        try:
            self.redis_client = redis.Redis(
                host=redis_host,
                port=redis_port,
                db=redis_db,
                decode_responses=False
            )
            # 测试连接
            self.redis_client.ping()
            self.enabled = True
            logger.info("✅ Redis缓存已启用")
        except:
            self.redis_client = None
            self.enabled = False
            logger.warning("⚠️ Redis不可用，缓存已禁用")

    def _generate_key(self, symbol: str, start_date: datetime,
                      end_date: datetime, interval: str, data_type: str) -> str:
        """生成缓存键"""
        key_string = f"{symbol}_{start_date.strftime('%Y%m%d')}_{end_date.strftime('%Y%m%d')}_{interval}_{data_type}"
        return hashlib.md5(key_string.encode()).hexdigest()

    def get(self, symbol: str, start_date: datetime, end_date: datetime,
            interval: str, data_type: str) -> Optional[Any]:
        """获取缓存数据"""
        if not self.enabled:
            return None

        try:
            key = self._generate_key(symbol, start_date, end_date, interval, data_type)
            cached_data = self.redis_client.get(key)

            if cached_data:
                data = pickle.loads(cached_data)
                logger.info(f"🎯 缓存命中: {symbol} {data_type}")
                return data

        except Exception as e:
            logger.error(f"获取缓存失败: {e}")

        return None

    def set(self, symbol: str, start_date: datetime, end_date: datetime,
            interval: str, data_type: str, data: Any, expire_hours: int = 24):
        """设置缓存数据"""
        if not self.enabled or data is None:
            return

        try:
            key = self._generate_key(symbol, start_date, end_date, interval, data_type)
            serialized_data = pickle.dumps(data)

            # 设置过期时间
            expire_seconds = expire_hours * 3600
            self.redis_client.setex(key, expire_seconds, serialized_data)

            logger.info(f"💾 数据已缓存: {symbol} {data_type}")

        except Exception as e:
            logger.error(f"设置缓存失败: {e}")

    def clear_cache(self, pattern: str = "*"):
        """清理缓存"""
        if not self.enabled:
            return

        try:
            keys = self.redis_client.keys(pattern)
            if keys:
                self.redis_client.delete(*keys)
                logger.info(f"🗑️ 已清理{len(keys)}个缓存项")
        except Exception as e:
            logger.error(f"清理缓存失败: {e}")
